package com.chen.function_demo.chapter2;

/**
 * 第二章第五节
 * @author 陈哲<p>
 * ================================<p>
 * Date: 2025/5/11<p>
 * Time: 19:14<p>
 * ================================
 */
public class Section5 {
    /*
        柯里化：将一个多参数函数转换成一系列接收单参数的函数（需要结合闭包使用）
        柯里化的作用：让函数分步执行
     */

    /**
     * 模拟一个手机类
     */
    static class Phone {
        String cpu;
        String memory;
        String disk;
        String assemble;
        String brand;

        public Phone(String cpu, String memory, String disk, String assemble, String brand) {
            this.cpu = cpu;
            this.memory = memory;
            this.disk = disk;
            this.assemble = assemble;
            this.brand = brand;
        }

        public String toString() {
            return "Phone{" +
                    "cpu='" + cpu + '\'' +
                    ", memory='" + memory + '\'' +
                    ", disk='" + disk + '\'' +
                    ", assemble='" + assemble + '\'' +
                    ", brand='" + brand + '\'' +
                    '}';
        }
    }

    /**
     * 模拟一个简单的手机组装的例子
     */
    @FunctionalInterface
    interface Factory {
        Phone leaveTheFactory(String cpu,
                              String memory,
                              String disk,
                              String assemble,
                              String brand);
    }

    public static void main(String[] args) {
        // 多参数函数
        Factory factory = Phone::new;
        System.out.println(factory.leaveTheFactory("麒麟", "16G", "256G", "组装", "华为"));
        // 将其转化为一系列单参数函数 函数返回值是下一步的函数
        /*Cpu cpu = (cpu) -> {
            return Memory => (memory) ->  {
                return Disk => (disk) ->  {
                    return Assemble => (assemble) ->  {
                        return Brand => (brand) ->  {
                            return Factory => (cpu, memory, disk, assemble, brand) -> {
                                return new Phone(cpu, memory, disk, assemble, brand);
                            }
                        }
                    }
                }
            }
        };*/
        Cpu cpu1 = (cpu) -> (memory) -> (disk) -> (assemble) -> (brand) -> Phone::new;
        System.out.println(cpu1.cpu("麒麟").memory("16G").disk("256G").assemble("组装").brand("华为").leaveTheFactory("麒麟", "16G", "256G", "组装", "华为"));
    }

    @FunctionalInterface
    interface Cpu {
        Memory cpu(String cpu);
    }

    @FunctionalInterface
    interface Memory {
        Disk memory(String memory);
    }

    @FunctionalInterface
    interface Disk {
        Assemble disk(String disk);
    }

    @FunctionalInterface
    interface Assemble {
        Brand assemble(String assemble);
    }

    @FunctionalInterface
    interface Brand {
        Factory brand(String brand);
    }
}
